/**
 * Aurora 简易订阅发布部分
 */

/**
 * 事件列表
 * 里面每一个参数都是 Array(Function) | Array(Object)
 * 
 * object 为:
 * {
 *   name : <string>,
 *   func : <function>
 * }
 */
var events = {};

/**
 * 注册监听的事件
 * @param event  String|Array(String)
 *  想要接受的事件类型
 * @param callback  Function(event, argv)
 *  回调函数
 * @param name
 *  名称. 为这个事件添加一个名称, 允许它能够被找到
 */
function subscribe (event, callback, name) {
  if (typeof event == 'string') {
    this.subscribeOne(event, callback, name);
  } else if (event instanceof Array) {
    var len = event.length;
    for (var i = 0; i < len; i++) {
      this.subscribe(event[i], callback, name);
    }
  }
};

/**
 * 注册一个监听的事件
 * @param event  String
 *  想要接受的事件类型
 * @param callback  Function(event, argv)
 *  回调函数
 * @param name
 *  名称. 为这个事件添加一个名称, 允许它能够被找到
 */
function subscribeOne (event, callback, name) {
  var funcs = events[event];
  if (funcs == null) {
    funcs = [];
    events[event] = funcs;
  }
  
  if (name != null) {
    funcs.push({
      name : name,
      func : callback
    });
  } else {
    funcs.push(callback);
  }
};

/**
 * 发布事件
 * @param {string} event
 *   事件名称
 * @param {any} argv
 *   其它附属参数
 * @return Promise 参数
 */
function release (event, argv) {
  var funcs = events[event];
  
  if (funcs == null || funcs.length == 0) {
    console.log("release no-response: " + event);
    console.log(argv);
    return Promise.resolve([]);
  }
  
  function createPromise(func) {
    var f = func;
    if (typeof(f) == 'object') {
      f = f.func;
    }
    
    if (typeof(f) == 'function') {
      return Promise.resolve(f(event, argv));
    } else {
      console.error("monitor-message: 无法解析下列事件监听", event);
      console.error(func);
    }
  }
  
  var ps = [];
  var len = funcs.length;
  for (var i = 0; i < len; i++) {
    ps.push(createPromise(funcs[i]));
  }
  
  return Promise.all(ps);
};

/**
 * 删除 name 对应的所有的 func
 */
function remove (name) {
  for (var key in events) {
    var array = events[key];
    
    for (var i = array.length - 1; i >= 0; i--) {
      var o = array[i];
      if (typeof(o) == 'object') {
        if (o.name == name) {
          array.splice(i, 1);
        }
      }
    }
    
    if (array == null) {
      delete events[key];
    }
  }
};

global.release = release;

export default {subscribe, subscribeOne, release, remove};
